Матч
449, Нечетные делители (OddDivisors)
Дивизион 2,
Уровень 2
Пусть f(n) - наибольший нечетный делитель
натурального числа n. По заданному
натуральному n необходимо вычислить
значение суммы f(1) + f(2) + ... + f(n).
Класс: OddDivisors
Метод: long
findSum(int n)
Ограничения: 1 £ n £ 1000000000.
Вход. Натуральное число n.
Выход. Значение суммы f(1) + f(2) + ... + f(n).
Пример входа
n |
7 |
1 |
777 |
Пример выхода
21
1
201537
РЕШЕНИЕ
рекурсия
Если число n нечетное, то f(n)
= n. Если число n
четное, то f(n) = f(n / 2).
Пусть g(n) = f(1) + f(2)
+ ... + f(n).
Рзазобъем множество натуральных чисел от 1 до n на два подмножества: нечетных ODD = {1, 3, 5, …, 2k – 1} и четных EVEN = {2, 4, 6, …, 2l} чисел. Предполагаем, что среди натуральных чисел от 1 до n имеется в точности k = нечетных и l
= четных чисел.
Тогда f(1) + f(3)
+ f(5) + ... + f(2k – 1) = 1 + 3 + 5 + …
+ (2k – 1) = = k2.
В то же время f(2) + f(4)
+ f(6) + ... + f(2l) = f(1) + f(2)
+ f(3) + ... + f(l) = g(l) = .
Таким образом g(n)
= k2 + . Для окончания рекурсии положим g(0) = 0.
ПРОГРАММА
#include <stdio.h>
class OddDivisors
{
public:
long long findSum(long long n)
{
long
long k = (n + 1) / 2;
if (n == 0) return
0;
return k * k + findSum(n / 2);
}
};